import hashlib
import time
from logging.handlers import RotatingFileHandler

from flask import json, request, session, jsonify
from flask_cors import CORS
import json;
import os;
import logging

from db.mysql.MySql import MySql
from framework.EException import EException

from flask import Flask

from services.MemberActivityRecordService import MemberActivityRecordService
from services.MemberService import MemberService

memberController = Flask(__name__)
memberController.config['SECRET_KEY'] = os.urandom(24)  # 生成24位的随机数种子，用于产生SESSION ID
memberController.config['JSON_AS_ASCII'] = False

env_dist = os.environ # environ是在os.py中定义的一个dict environ = {}
signKey="2650a17f769d40f0a899f4385977c5a2";

mySql=None;# MySql(db_add,db_user,db_pwd,db_name)
service=None;#MemberService(mySql)

logging.basicConfig(level=logging.DEBUG)
#日志
def setup_log():
    """配置日志"""
    #datetime.datetime.strptime(string,'%Y-%m-%d %H:%M:%S')
    # 设置日志的记录等级
    logging.basicConfig(level=logging.DEBUG)  # 调试debug级
    # 创建日志记录器，指明日志保存的路径、每个日志文件的最大大小、保存的日志文件个数上限
    file_log_handler = RotatingFileHandler("logs/log.log", maxBytes=1024 * 1024 * 100, backupCount=10)
    # 创建日志记录的格式 日志等级 输入日志信息的文件名 行数 日志信息
    formatter = logging.Formatter('%(levelname)s %(filename)s:%(lineno)d %(message)s')
    # 为刚创建的日志记录器设置日志记录格式
    file_log_handler.setFormatter(formatter)
    # 为全局的日志工具对象（flask app使用的）添加日志记录器
    logging.getLogger().addHandler(file_log_handler)

#全局可跨域请求
CORS(memberController, supports_credentials=True)
CORS(memberController, resources=r'/*')

@memberController.before_request
def before():
    """
    针对app实例定义全局拦截器
    """
    service=MemberService(memberController.config['db']);
    url = request.path  # 读取到当前接口的地址
    s="http[{0}]:{1}".format(request.method,request.url)
    if request.method=="POST":
        s=s+"\n\t请求参数：{0}".format(request.json);
    logging.info(s);
    if url == '/sess':
        pass
    elif session.get('is_login', '') != 'true':
        #return '你还没有登录'
        pass
    else:
        pass

def sign_JsonBody(body, signKey):
    '''请求body sign签名'''
    # 列表生成式，生成key=value格式
    #a = ["".join(i) for i in body.items() if i[1] and i[0] != "sign"]
    d1 = json.dumps(body, sort_keys=True, indent=4,separators=(',',':'));
    #print(d1)
    body=json.loads(d1);
    a="";
    for key in body:
        a=a+key+"="+str(body[key])+"&";
    #a=a[:-1];
    #print(a)
    # 参数名ASCII码从小到大排序
    #strA = a+"sign=""".join(sorted(a))
    # 在strA后面拼接上apiKey得到striSignTemp字符串
    striSignTemp = a+"sign="+signKey

    # MD5加密
    def jiamimd5(src):
        m = hashlib.md5()
        m.update(src.encode('UTF-8'))
        return m.hexdigest()
    sign = jiamimd5(striSignTemp.lower())
    # 得到sign签名后新的body值
    body["sign"] = sign
    return body

@memberController.after_request
def after(response):
    if response.status_code==200:
        if (response.is_json):
            js=response.json;
            if ("code" in js):
                js["timestamp"]=int(time.time());
                js["success"] = False;
                result=js;
            else:
                result = {
                    "success": True,
                    "message": "",
                    "code": response.status_code,
                    "result": js,
                    "timestamp": int(time.time())
                };
            result=sign_JsonBody(result,signKey);
            response = jsonify(result);
    logging.info("\t返回信息："+str(response.json));
    return response;

def checkJsonKey(json, *keys):
    if (len(keys)==0):
        raise EException(501,"参数错误");
    for key in keys:
        if (key not in json):
            raise EException(501,"请求参数不完整【%s】" % key);

#会员登录
@memberController.route('/login',methods=['post'])
def post_login():

    deviceId= request.headers.get('deviceId');
    memberId = request.headers.get('memberId');
    postData=request.json;
    memberService=MemberService(mySql);
    postData["deviceId"]=deviceId;
    resData=memberService.login(postData);
    return resData;
#会员注册
@memberController.route('/register',methods=['post'])
def post_register():
    try:
        deviceId= request.headers.get('deviceId');
        memberId = request.headers.get('memberId');
        postData=request.json;
        checkJsonKey(postData, "deviceId", "loginType");
        memberService=MemberService(mySql);
        postData["deviceId"]=deviceId;
        resData=memberService.register(postData);
        return resData;
    except EException as e:
        return {
            "code": e.args[0],
            "message": e.args[1]
        }
    except Exception as e:
        return {
            "code": 500,
            "message": repr(e)
        }

def getMemberInfo(request):
    memberId = request.headers.get('memberId');
    member=mySql.selectOne("select * from bis_member where id='"+memberId+"'");
    if (member==None):
        raise EException(-1,"会员不存在")

@memberController.route('/addMyMusicItem',methods=['post'])
def post_addMyMusicItem():
    try:
        postData = request.json;
        checkJsonKey(postData, "itemInfo", "musicInfo");
        member = getMemberInfo(request);
        memberService = MemberService(mySql);
        music= memberService.addMyMusicItem(postData,member);
        return music;
    except EException as e:
        return {
            "code": e.args[0],
            "message": e.args[1]
        }
    except Exception as e:
        return {
            "code": 500,
            "message": repr(e)
        }

@memberController.route('/getMyMusicList',methods=['get'])
def get_getMyMusicList():
    memberId = request.headers.get('memberId');
    pageIndex=request.args.get('pageIndex')
    pageSize = request.args.get('pageSize')
    list=service.getMyMusicList(memberId,pageIndex,pageSize);
    result = {
        "success": True,
        "message": "",
        "code": 200,
        "result": list
    };
    return result;

@memberController.route('/getActivityRecords',methods=['get'])
def get_getActivityRecords():
    mid=request.args.get("mid");
    atype=request.args.get('atype')
    pageNo=request.args.get('pageNo')
    pageSize=request.args.get('pageSize')
    if (pageNo==None):
        pageNo=1
    if (pageSize==None):
        pageSize=10;
    memberActivityRecordService=MemberActivityRecordService(mySql)
    page = memberActivityRecordService.getRecords(mid, atype,pageNo,pageSize);
    return page;


